﻿#pragma once

#include <Windows.h>
#include <string>
#include <d3dcompiler.h>
#include <memory>
#include "Log.h"
#include "Timer.h"
#include "Graphics.h"
#include "Misc.h"
#include "Keyboard.h"
#include "Mouse.h"
#include "WinFunc.h"


namespace Base {

	class BaseApp {
	public:
		static BaseApp* s_BaseApp;
		BaseApp();
		virtual ~BaseApp();

	public:

		void Init(HINSTANCE hInstance, int width, int height, const char* title);

		void StartMainLoop();

		LRESULT HandleMsg(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

	public:

		int GetWidth() const { return m_Width; }
		int GetHeight() const { return m_Height; }
		Graphics* GetGraphics() const { return m_graphics.get(); }
		Timer* GetTimer() const { return m_timer.get(); }
		inline void SetIMGUI(bool flag) {
			mEnableIMGUI = flag;
		}

	protected:

		// 子类需要重写的方法
		virtual void OnResize() = 0;
		virtual void OnInit() = 0;
		virtual void OnGUI() = 0;
		virtual void OnInput() = 0;
		virtual void OnUpdate() = 0;
		virtual void OnFrame() = 0;
		virtual void OnTerminate() = 0;

	private:

		void BeginFrame();
		void EndFrame();

	private:

		void InitWindow();
		void InitImGUI();
		void ReleaseImGUI();

	protected:

		// 一些组件
		std::unique_ptr<Log> m_log;
		std::unique_ptr<Timer> m_timer;
		std::unique_ptr<Graphics> m_graphics;
		std::unique_ptr<Keyboard> m_keyboard;
		std::unique_ptr<Mouse> m_mouse;

		// 窗口相关
		int m_Width, m_Height;
		std::string m_title;

		// 
		HINSTANCE m_hInstance;
		std::string m_windowClzName;
		HWND m_hWnd;

		// 
	private:
		bool mEnableIMGUI;
	};
}
